home *** CD-ROM | disk | FTP | other *** search
/ PC Media 2 / PC MEDIA CD02.iso / share / prog / tpsorts / tursort.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1985-10-23  |  23.8 KB  |  704 lines

  1. Program Tursort (output);
  2. {*************************************************************************}
  3. {                                                                         }
  4. { Program: Tursort.Pas                                                    }
  5. { Programmer: Keith Shafer                                                }
  6. {             San Diego, CA                                               }
  7. {                                                                         }
  8. { This program contains various sort routines that can be used in         }
  9. { programs that you write.  These routines were found in the book titled  }
  10. { Data Structures Using Pascal by Tenenbaum and Augenstein. The           }
  11. { sample routines listed below sort integers.  They can be modified       }
  12. { to sort other data.  I encourage users to add routines not listed       }
  13. { and to modify the sample program at the bottom of the end of the        }
  14. { listing.  The idea for this program came from one I have seen in the    }
  15. { public domain dealing with sort algorithms for the 'BASIC' language.    }
  16. { I hope that in some way these procedures will help you.                 }
  17. {*************************************************************************}
  18.  
  19. Const Numelts  = 250;    { change these constants for different }
  20.       Abovelts = 251;    { time comparisons.                    }
  21.  
  22. Type Arraytype = array[1..Numelts] of Integer;
  23.      Aptr      = 1..Numelts;
  24.      Aptr2     = 0..Abovelts;
  25.  
  26. Var X,Y : Arraytype;
  27.     N   : Aptr;
  28.  
  29.  
  30. procedure time;
  31. type
  32.   regpack = record
  33.               ax,bx,cx,dx,bp,si,di,ds,es,flags: integer;
  34.             end;
  35.  
  36. var
  37.   recpack:          regpack;             {assign record}
  38.   ch,cl,dh,dl:      integer;
  39.  
  40. begin
  41.   with recpack do
  42.     ax := $2c00;                             {initialize correct registers}
  43.   intr($21,recpack);                     {call interrupt}
  44.   with recpack do begin
  45.     ch:=Hi(cx);cl:=Lo(cx);
  46.     dh:=Hi(dx);dl:=Lo(dx);
  47.     end;
  48.     write(dh:4,dl:4);
  49. end;
  50.  
  51.  
  52. (*************************************************************************)
  53.  
  54. Procedure Bubble_Sort_V1 (Var X: Arraytype; N: Aptr);
  55.  
  56. Var Last, Current : Aptr;
  57.     Hold          : Integer;
  58.  
  59. Begin
  60.     for Last:=N downto 2
  61.     do begin
  62.            for Current:=1 to N-1
  63.            do begin
  64.                   if X[Current] >= X[Current+1]
  65.                      then begin
  66.                               Hold:=X[Current];
  67.                               X[Current]:=X[Current+1];
  68.                               X[Current+1]:=Hold;
  69.                           end;
  70.            end;
  71.     end;
  72. End;
  73.  
  74. (*************************************************************************)
  75.  
  76. Procedure Bubble_Sort_V2 (Var X: Arraytype; N: Aptr);
  77.  
  78. Var Pass, J  : Aptr;
  79.     Intchnge : Boolean;
  80.     Hold     : Integer;
  81.  
  82. Begin
  83.     Intchnge:=true;
  84.     Pass:=1;
  85.     While (Pass <= N-1) and (Intchnge)
  86.       { outer loop controls the number of passes }
  87.       do begin
  88.              Intchnge:=false;  { initially no interchanges have been made }
  89.                                { in this pass                             }
  90.              for J:=1 to N-Pass
  91.              { inner loop governs each individual pass }
  92.              do if X[J] >= X[J+1] { elements out of order }
  93.                    then begin
  94.                             { an interchange is necessary }
  95.                             Intchnge:=true;
  96.                             Hold:=X[J];
  97.                             X[J]:=X[J+1];
  98.                             X[J+1]:=Hold;
  99.                         end;
  100.              Pass:=Pass+1;
  101.       end;
  102. End;
  103.  
  104. (*************************************************************************)
  105.  
  106. Procedure QuickSort_V1 (Var X: Arraytype; N: Aptr);
  107.  
  108.    Procedure Quick (lb,ub : Aptr2);
  109.  
  110.    Var J : Aptr;
  111.  
  112.        Procedure Rearrange (lb,ub: Aptr2; Var J: Aptr);
  113.  
  114.        Var Up, Down : Aptr;
  115.            A        : Integer;
  116.  
  117.        Begin
  118.            A:=X[lb];
  119.            J:=lb;
  120.            Up:=ub;
  121.            Down:=lb;
  122.            repeat
  123.                while (up > down) and (X[Up] >= A)
  124.                   do Up:=Up-1;
  125.                J:=Up;
  126.                if Up <> Down
  127.                   then begin
  128.                            X[Down]:=X[Up];
  129.                                  { move up the array }
  130.                            while (Down < Up) and (X[Down] <= A)
  131.                               do Down:=Down+1;
  132.                            J:=Down;
  133.                            if Down <> Up
  134.                               then X[Up]:=X[Down];
  135.                        end;
  136.            until Down = Up;
  137.            X[J]:=A;
  138.        End; { procedure rearrange }
  139.  
  140.    Begin { procedure quick }
  141.        if lb < ub
  142.           then begin
  143.                    rearrange(lb,ub,j);
  144.                    quick(lb,j-1);
  145.                    quick(j+1,ub);
  146.                end;
  147.    End; { procedure quick }
  148.  
  149. Begin { procedure quicksort V1 }
  150.     quick(1,N);
  151. End;  { procedure quicksort V1 }
  152.  
  153. (*************************************************************************)
  154.  
  155. Procedure QuickSort_V2 (Var X: Arraytype; N: Aptr);
  156.  
  157. Type Stackitem = record
  158.                    lb : Aptr2;
  159.                    ub : Aptr2;
  160.                  end;
  161.      Stack = record
  162.                top : 0..Numelts;
  163.                item: array[1..Numelts] of Stackitem;
  164.              end;
  165.  
  166. Var S : Stack;
  167.     Newbnds : Stackitem;
  168.     I, J    : Aptr;
  169.  
  170.        Procedure Rearrange (lb,ub: Aptr2; Var J: Aptr);
  171.  
  172.        Var Up, Down : Aptr;
  173.            A        : Integer;
  174.  
  175.        Begin
  176.            A:=X[lb];
  177.            J:=lb;
  178.            Up:=ub;
  179.            Down:=lb;
  180.            repeat
  181.                while (up > down) and (X[Up] >= A)
  182.                   do Up:=Up-1;
  183.                J:=Up;
  184.                if Up <> Down
  185.                   then begin
  186.                            X[Down]:=X[Up];
  187.                                  { move up the array }
  188.                            while (Down < Up) and (X[Down] <= A)
  189.                               do Down:=Down+1;
  190.                            J:=Down;
  191.                            if Down <> Up
  192.                               then X[Up]:=X[Down];
  193.                        end;
  194.            until Down = Up;
  195.            X[J]:=A;
  196.        End; { procedure rearrange }
  197.  
  198.        Procedure Push (Var S: Stack; X: Stackitem);
  199.  
  200.        Begin
  201.            S.top:=S.top+1;
  202.            S.item[S.top]:=X;
  203.        End; { procedure push }
  204.  
  205.        Function Empty (S: Stack): Boolean;
  206.  
  207.        Begin
  208.            if S.top = 0
  209.               then empty:=true
  210.               else empty:=false;
  211.        End; { function empty }
  212.  
  213.        Procedure Popsub (Var S: Stack; Var X: Stackitem);
  214.  
  215.        Begin
  216.            if empty(S)
  217.               then writeln ('Error....Stack Underflow')
  218.               else begin
  219.                        X:=S.item[S.top];
  220.                        S.top:=s.top-1;
  221.                    end;
  222.        End; { function popsub }
  223.  
  224. Begin
  225.     S.top:=0;
  226.     with newbnds
  227.          do begin
  228.                 lb:=1;
  229.                 ub:=N;
  230.                 push(S,newbnds);
  231.                 { repeat as long as there are     }
  232.                 { unsorted subarrays on the stack }
  233.                 while not empty(S)
  234.                       do begin
  235.                              popsub(S,newbnds);
  236.                              while ub > lb
  237.                                    do begin
  238.                                           { process next subarray }
  239.                                           rearrange(lb,ub,j);
  240.                                           { stack the larger subarray }
  241.                                           if j-lb > ub-j
  242.                                           { stack the first subarray }
  243.                                              then begin
  244.                                                       I:=ub;
  245.                                                       ub:=j-1;
  246.                                                       push(S,newbnds);
  247.                                                       { process 2nd subarray }
  248.                                                       lb:=j+1;
  249.                                                       ub:=I;
  250.                                                   end
  251.                                           { stack the second subarray }
  252.                                           else begin
  253.                                                    I:=lb;
  254.                                                    lb:=j+1;
  255.                                                    push(S,newbnds);
  256.                                                    { process 1st subarray }
  257.                                                    lb:=I;
  258.                                                    ub:=j-1;
  259.                                                end;
  260.                                       end;
  261.                          end;
  262.             end;
  263. End; { procedure quicksort V2 }
  264.  
  265. (*************************************************************************)
  266.  
  267. Procedure Selection_Sort (Var X: Arraytype; N: Aptr);
  268.  
  269. Var I, J, Index : Aptr;
  270.     Large       : Integer;
  271.  
  272. Begin
  273.     for I:=N downto 2
  274.         do begin
  275.                { place the largest number of X[1] through }
  276.                { X[1] into large and its index into index }
  277.                Large:=X[1];
  278.                Index:=1;
  279.                for J:=2 to I
  280.                    do if X[J] > Large
  281.                          then begin
  282.                                   Large:=X[J];
  283.                                   Index:=J;
  284.                               end;
  285.                { place large into position I }
  286.                X[Index]:=X[I];
  287.                X[I]:=Large;
  288.            end;
  289. End; { procedure selection sort }
  290.  
  291. (*************************************************************************)
  292.  
  293. Procedure Heap_Sort (Var X: Arraytype; N: Aptr);
  294.  
  295. { N must be >= 3 }
  296.  
  297. Label 10, 11;
  298.  
  299. Var I, J, K, Y: Integer;
  300.  
  301. Begin
  302.     { create initial heap }
  303.     for K:=2 to N
  304.         do begin
  305.                { insert X[K] into existing heap of size K-1 }
  306.                I:=K;
  307.                Y:=X[K];
  308.                J:=I div 2;
  309.            while J>0
  310.                 do begin
  311.                        if Y <= X[J]
  312.                           then goto 10;
  313.                        X[I]:=X[J];
  314.                        I:=J;
  315.                        J:=I div 2;
  316.                    end;
  317. 10:            X[I]:=Y;
  318.            end;
  319.     { We remove X[1] and place it in its proper position }
  320.     { in the array.  We then adjust the heap.            }
  321.     for K:=N downto 2
  322.         do begin
  323.                Y:=X[K];
  324.                X[K]:=X[1];
  325.                { readjust the heap of order k-1           }
  326.                { move y down the heap for proper position }
  327.                I:=1;
  328.                J:=2;
  329.                if (X[3] > X[2]) and (K-1 >= 3)
  330.                   then J:=3;
  331.                { J is the larger son of I }
  332.                { in the heap of size K-1  }
  333.                While J <= K-1
  334.                      do begin
  335.                             if X[J] <= Y
  336.                                then goto 11;
  337.                             X[I]:=X[J];
  338.                             I:=J;
  339.                             J:=2*I;
  340.                             if J+1 <= K-1
  341.                                then if X[J+1] > X[J]
  342.                                        then J:=J+1;
  343.                         end;
  344. 11:            X[I]:=Y;
  345.            end;
  346. End; { procedure heap sort }
  347.  
  348. (*************************************************************************)
  349.  
  350. Procedure Insert_Sort(Var X: Arraytype; N: Aptr);
  351.  
  352. Var K: Aptr;
  353.     I: Aptr2;
  354.     Y: Integer;
  355.     Found: Boolean;
  356.  
  357. Begin
  358.     { Initially X[1] may be thought of as a sorted file }
  359.     { of one element.  After each repetition of the     }
  360.     { following loop, the elements X[1] through X[K] are in order }
  361.     for K:=2 to N
  362.         do begin
  363.                { insert X[K] into the sorted file }
  364.                Y:=X[K];
  365.                { move down one position all numbers }
  366.                { greater than y }
  367.                I:=K-1;
  368.                Found:=false;
  369.                While (I >= 1) and (not found)
  370.                      do if Y < X[I]
  371.                         then begin
  372.                                  X[I+1]:=X[I];
  373.                                  I:=I-1;
  374.                              end
  375.                          else found:=true;
  376.                { insert Y at proper position }
  377.                X[I+1]:=Y;
  378.            end;
  379. End; { procedure insert }
  380.  
  381. (*************************************************************************)
  382.  
  383. Procedure Merge_Sort(Var X: Arraytype; N: Aptr);
  384.  
  385. Var Aux : Arraytype;
  386.     lb2, ub1, ub2 : Aptr;
  387.     lb1, I, J, K  : Aptr2;
  388.     Size : Integer;
  389.  
  390. Begin
  391.     Size:=1; { merge files of size 1 }
  392.     while Size < N
  393.           do begin
  394.                  lb1:=1; { initialize lower bound of first file }
  395.                  K:=1;   { K is index for auxiliary array       }
  396.                  while lb1+Size <= N
  397.                        { check if there are two files to merge }
  398.                        do begin
  399.                               { compute remaining indices }
  400.                               lb2:=lb1+Size;
  401.                               ub1:=lb2-1;
  402.                               if lb2+Size-1 > N
  403.                                  then ub2:=N
  404.                                  else ub2:=lb2+Size-1;
  405.                               { proceed through the two subfiles }
  406.                               I:=lb1;
  407.                               J:=lb2;
  408.                               while (I <= ub1) and (J <= ub2)
  409.                                     do begin
  410.                                            { enter smaller into the array aux }
  411.                                            if X[I] <= X[J]
  412.                                               then begin
  413.                                                        Aux[K]:=X[I];
  414.                                                        I:=I+1;
  415.                                                    end
  416.                                               else begin
  417.                                                        Aux[K]:=X[J];
  418.                                                        J:=J+1;
  419.                                                    end;
  420.                                             K:=K+1;
  421.                                        end;
  422.                               { At this point one of the subfiles }
  423.                               { has been exahusted. Insert any    }
  424.                               { remaining portions of the other file }
  425.                               while I <= ub1
  426.                                     do begin
  427.                                            Aux[K]:=X[I];
  428.                                            I:=I+1;
  429.                                            K:=K+1;
  430.                                        end;
  431.                               while J <= ub2
  432.                                     do begin
  433.                                            Aux[K]:=X[J];
  434.                                            J:=J+1;
  435.                                            K:=K+1;
  436.                                        end;
  437.                               { advance lb1 to start of next pair of files }
  438.                               lb1:=ub2+1;
  439.                           end;
  440.                           { copy any remaining single file }
  441.                           I:=lb1;
  442.                           while K <= N
  443.                                 do begin
  444.                                        Aux[K]:=X[I];
  445.                                        K:=K+1;
  446.                                        I:=I+1;
  447.                                    end;
  448.                           { adjust x and size }
  449.                           for K:=1 to N
  450.                               do X[K]:=Aux[K];
  451.                           Size:=Size * 2;
  452.              end;
  453. End; { procedure merge sort }
  454.  
  455. (*************************************************************************)
  456.  
  457. Procedure Radix_Sort(Var X: Arraytype; N: Aptr);
  458.  
  459. Const M = 3; { number of digits in numelts }
  460.  
  461. Type Nodetype = Record
  462.                   Info: Integer;
  463.                   Next: Aptr2;
  464.                 End;
  465.  
  466. Var Node: Array[1..Numelts] of Nodetype;
  467.     Front: Array[0..10] of Aptr2;
  468.     Rear: Array[0..9] of Aptr2;
  469.     P: Aptr;
  470.     First, Q, I, J: Aptr2;
  471.     Y, Expon, K: Integer;
  472.  
  473. Begin
  474.     { intialize linked list }
  475.     for I:=1 to N-1
  476.         do begin
  477.                Node[I].Info:=X[I];
  478.                Node[I].Next:=I+1;
  479.            end;
  480.     Node[N].Info:=X[N];
  481.     Node[N].Next:=0;
  482.     First:=1; { first is the head of the linked list }
  483.     for K:=1 to M
  484.         { M is the number of digits in the numbers }
  485.         do begin
  486.                for I:=0 to 9
  487.                    do Rear[I]:=0;
  488.                for I:=0 to 10
  489.                    do Front[I]:=0; { initialize queues }
  490.                { process each element on the list }
  491.                while First <> 0
  492.                      do begin
  493.                             P:=First;
  494.                             First:=Node[First].Next;
  495.                             Y:=Node[P].Info;
  496.                             { extract kth digit }
  497.                             Expon:=1;
  498.                             for I:=1 to K-1
  499.                                 do Expon:=Expon * 10;
  500.                             J:=(Y div Expon) mod 10;
  501.                             { insert y into queue[j] }
  502.                             Q:=Rear[J];
  503.                             If Q = 0
  504.                                then Front[J]:=P
  505.                             else Node[Q].Next:=P;
  506.                             Rear[J]:=P;
  507.                         end;
  508.                { at this point each record is in }
  509.                { its proper queue based on digit }
  510.                { k. We now form a single list    }
  511.                { from all the queue elements     }
  512.                { Find the first element          }
  513.                J:=0;
  514.                While (J <= 9) and (Front[J]=0)
  515.                      do J:=J+1;
  516.                First:=Front[J];
  517.                { link up remaining queues }
  518.                while J <= 9
  519.                      { check if finished }
  520.                      do begin
  521.                             { find next element }
  522.                             I:=J+1;
  523.                             while (I<=9) and (Front[I]=0)
  524.                                   do I:=I+1;
  525.                             if I <= 9
  526.                                then begin
  527.                                         P:=I;
  528.                                         Node[Rear[J]].Next:=Front[I];
  529.                                     end;
  530.                             J:=I;
  531.                         end;
  532.                Node[Rear[P]].Next:=0;
  533.            end; { for...do begin }
  534.     { copy back to original array }
  535.     for I:=1 to N
  536.         do begin
  537.                X[I]:=Node[First].Info;
  538.                First:=Node[First].Next;
  539.            end;
  540. End; { procedure radix sort }
  541.  
  542. (*************************************************************************)
  543.  
  544. Procedure Worst_Case_Array(Var X: Arraytype);
  545.  
  546. Var I : Integer;
  547.  
  548. Begin
  549.     for I:=1 to Numelts
  550.         do begin
  551.                X[I]:=numelts-I;
  552.            end;
  553. End; { procedure worst case array }
  554.  
  555. Procedure Best_Case_Array(Var X: Arraytype);
  556.  
  557. Var I : Integer;
  558.  
  559. Begin
  560.     for I:=1 to numelts
  561.         do begin
  562.                X[I]:=I;
  563.            end;
  564. End; { procedure best case array }
  565.  
  566. Procedure Random_Case_Array(Var X: Arraytype);
  567.  
  568. Var I : Integer;
  569.  
  570. Begin
  571.     for I:=1 to numelts
  572.         do begin
  573.                X[I]:=Random(numelts);
  574.            end;
  575. End; { procedure random case array }
  576.  
  577.  
  578. Procedure Print_Array(X: Arraytype);
  579.  
  580. Var I : Integer;
  581.  
  582. Begin
  583.     for I:=1 to numelts
  584.         do begin
  585.                writeln(X[I]);
  586.                delay(50);
  587.            end;
  588. End; { procedure print array }
  589.  
  590. Procedure Copy_Array(X: Arraytype; Var Y: Arraytype);
  591.  
  592. Var I: Integer;
  593.  
  594. Begin
  595.     for I:=1 to numelts
  596.         do begin
  597.                Y[I]:=X[I];
  598.            end;
  599. End; { procedure copy array }
  600.  
  601. Procedure Check_Array(Y: Arraytype);
  602.  
  603. Var I: Integer;
  604.     Result: Boolean;
  605.  
  606. Begin
  607.     Result:=true;
  608.     for I:=1 to numelts-1
  609.         do begin
  610.                if Y[I] > Y[I+1] then Result:=false;
  611.            end;
  612.     if not Result then writeln ('Sorted incorrectly');
  613. End; { procedure check array }
  614.  
  615. (***********************************************)
  616.  
  617. Var I, J : Integer;
  618.  
  619. Begin
  620.     N:=numelts;
  621.     for I:=1 to 3
  622.         do begin
  623.                Case I of
  624.                     1: Worst_Case_Array(X);
  625.                     2: Best_Case_Array(X);
  626.                     3: Random_Case_Array(X);
  627.                end;
  628.                for J:=1 to 9
  629.                    do begin
  630.                           Copy_Array(X,Y);
  631.                           Case I of
  632.                                1: Write ('Numelts=',numelts,'..Worst Case Array...');
  633.                                2: Write ('Numelts=',numelts,'..Best Case Array....');
  634.                                3: Write ('Numelts=',numelts,'..Random Case Array..');
  635.                           end;
  636.                           Case J of
  637.                                1: Begin
  638.                                       Write ('Bubble Sort V1 Start.');
  639.                                       time;
  640.                                       Bubble_Sort_V1(Y,N);
  641.                                       time;
  642.                                   end;
  643.                                2: Begin
  644.                                       Write ('Bubble Sort V2 Start.');
  645.                                       time;
  646.                                       Bubble_Sort_V2(Y,N);
  647.                                       time;
  648.                                   end;
  649.                                3: Begin
  650.                                       Write ('Quick Sort V1 Start..');
  651.                                       time;
  652.                                       QuickSort_V1(Y,N);
  653.                                       time;
  654.                                   end;
  655.                                4: Begin
  656.                                       Write ('Quick Sort V2 Start..');
  657.                                       time;
  658.                                       QuickSort_V2(Y,N);
  659.                                       time;
  660.                                   end;
  661.                                5: Begin
  662.                                       Write ('Selection Sort Start.');
  663.                                       time;
  664.                                       Selection_Sort(Y,N);
  665.                                       time;
  666.                                   end;
  667.                                6: Begin
  668.                                       Write ('Heap Sort Start......');
  669.                                       time;
  670.                                       Heap_Sort(Y,N);
  671.                                       time;
  672.                                   end;
  673.                                7: Begin
  674.                                       Write ('Insert Sort Start....');
  675.                                       time;
  676.                                       Insert_Sort(Y,N);
  677.                                       time;
  678.                                   end;
  679.                                8: Begin
  680.                                       Write ('Merge Sort Start.....');
  681.                                       time;
  682.                                       Merge_Sort(Y,N);
  683.                                       time;
  684.                                   end;
  685.                                9: Begin
  686.                                       Write ('Radix Sort Start.....');
  687.                                       time;
  688.                                       Radix_Sort(Y,N);
  689.                                       time;
  690.                                   end;
  691.                           end;
  692.                           Check_Array(Y);
  693.                           Writeln;
  694.                       end; { J loop }
  695.                Writeln;
  696.            end; { I loop }
  697. End. { program tursort }
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.